/*userButton
Qiang.DAI
2025.08.30
YYYY.MM.DD
*/
#include "userButton.h"
#include "main.h"
#include "userInputPin.h"
#include "toolSM.h"
#include "toolList.h"
#include "stdio.h"
#include "stdlib.h"
#include "userBeep.h"
#include "userRemoteSys.h"
#include "userLed.h"


#undef SUCCESS
#define SUCCESS 0
#undef FAILED
#define FAILED  1

/*creat LinkList*/
K_List_t buttonList = newList();
ListNode_t buttonListHead = {NULL, NULL};

/*staitc function method*/
static uint8_t InitUserButten(struct buttonClass *p);

/*Button Action Methode,*/
static void FtButtonAction(SmEvent_t* event_p);
static void BkButtonAction(SmEvent_t* event_p);
static void RtButtonAction(SmEvent_t* event_p);
static void LfButtonAction(SmEvent_t* event_p);
static void Ax1ButtonAction(SmEvent_t* event_p);
static void Ax2ButtonAction(SmEvent_t* event_p);
static void Ax3ButtonAction(SmEvent_t* event_p);
static void Ax4ButtonAction(SmEvent_t* event_p);

/*Button GetStaus Run StateMachine*/
static uint8_t FtBtnGetStaus(struct buttonClass *p);
static uint8_t BkBtnGetStaus(struct buttonClass *p);
static uint8_t RtBtnGetStaus(struct buttonClass *p);
static uint8_t LfBtnGetStaus(struct buttonClass *p);
static uint8_t Ax1BtnGetStaus(struct buttonClass *p);
static uint8_t Ax2BtnGetStaus(struct buttonClass *p);
static uint8_t Ax3BtnGetStaus(struct buttonClass *p);
static uint8_t Ax4BtnGetStaus(struct buttonClass *p);




/*StateMachine Callback function */
void SM_buttonAction(SmEvent_t* tmpEvent);
/*creat Button StateTransTab*/
s_StateTransform_t FtBtnTranTab[] = {
    {STATE_btnFtUp,			EVENT_FtBtnDown, 		STATE_btnFtDown,		FtButtonAction},
    {STATE_btnFtDown,		EVENT_FtBtnUp, 			STATE_btnFtUp,			FtButtonAction},
};
s_StateTransform_t BkBtnTranTab[] = {
    {STATE_btnBkUp,			EVENT_BkBtnDown, 		STATE_btnBkDown,		BkButtonAction},
    {STATE_btnBkDown,		EVENT_BkBtnUp, 			STATE_btnBkUp,			BkButtonAction},
};
s_StateTransform_t RtBtnTranTab[] = {
    {STATE_btnRtUp,			EVENT_RtBtnDown, 		STATE_btnRtDown,		RtButtonAction},
    {STATE_btnRtDown,		EVENT_RtBtnUp, 			STATE_btnRtUp,			RtButtonAction},
};
s_StateTransform_t LfBtnTranTab[] = {
    {STATE_btnLfUp,			EVENT_LfBtnDown, 		STATE_btnLfDown,		LfButtonAction},
    {STATE_btnLfDown,		EVENT_LfBtnUp, 			STATE_btnLfUp,			LfButtonAction},
};
s_StateTransform_t Ax1BtnTranTab[] = {
    {STATE_btnAx1Up,			EVENT_Ax1BtnDown, 		STATE_btnAx1Down,		Ax1ButtonAction},
    {STATE_btnAx1Down,		EVENT_Ax1BtnUp, 			STATE_btnAx1Up,			Ax1ButtonAction},
};
s_StateTransform_t Ax2BtnTranTab[] = {
    {STATE_btnAx2Up,			EVENT_Ax2BtnDown, 		STATE_btnAx2Down,		Ax2ButtonAction},
    {STATE_btnAx2Down,		EVENT_Ax2BtnUp, 			STATE_btnAx2Up,			Ax2ButtonAction},
};
s_StateTransform_t Ax3BtnTranTab[] = {
    {STATE_btnAx3Up,			EVENT_Ax3BtnDown, 		STATE_btnAx3Down,		Ax3ButtonAction},
    {STATE_btnAx3Down,		EVENT_Ax3BtnUp, 			STATE_btnAx3Up,			Ax3ButtonAction},
};
s_StateTransform_t Ax4BtnTranTab[] = {
    {STATE_btnAx4Up,			EVENT_Ax4BtnDown, 		STATE_btnAx4Down,		Ax4ButtonAction},
    {STATE_btnAx4Down,		EVENT_Ax4BtnUp, 			STATE_btnAx4Up,			Ax4ButtonAction},
};


#define NEW_BUTTON(btnInputPin_ptr, btnTranstab,btnStausScan, smDefaultSta)	{			\
btnTranstab,																																			\
btnStausScan,																																			\
NULL,																																							\
btnInputPin_ptr,																																	\
1,																																								\
smDefaultSta,																																			\
}

k_Button_t g_btnFront = NEW_BUTTON(&remoteKey_Front,FtBtnTranTab,FtBtnGetStaus,STATE_btnFtUp);
k_Button_t g_btnBack = 	NEW_BUTTON(&remoteKey_Back,BkBtnTranTab,BkBtnGetStaus,STATE_btnBkUp);
k_Button_t g_btnRight = NEW_BUTTON(&remoteKey_Right,RtBtnTranTab,RtBtnGetStaus,STATE_btnRtUp);
k_Button_t g_btnLeft = 	NEW_BUTTON(&remoteKey_Left,LfBtnTranTab,LfBtnGetStaus,STATE_btnLfUp);
k_Button_t g_btnAux1 = 	NEW_BUTTON(&remoteKey_Aux1,Ax1BtnTranTab,Ax1BtnGetStaus,STATE_btnAx1Up);
k_Button_t g_btnAux2 = 	NEW_BUTTON(&remoteKey_Aux2,Ax2BtnTranTab,Ax2BtnGetStaus,STATE_btnAx2Up);
k_Button_t g_btnAux3 = 	NEW_BUTTON(&remoteKey_Aux3,Ax3BtnTranTab,Ax3BtnGetStaus,STATE_btnAx3Up);
k_Button_t g_btnAux4 = 	NEW_BUTTON(&remoteKey_Aux4,Ax4BtnTranTab,Ax4BtnGetStaus,STATE_btnAx4Up);



/*Init Button*/
uint8_t userButton_Init(void)
{
    InitUserButten(&g_btnFront);
    g_btnFront.mBtnStateMachine_ptr->mStateQty =  sizeof(FtBtnTranTab)/sizeof(FtBtnTranTab[0]);
    InitUserButten(&g_btnBack);
    g_btnBack.mBtnStateMachine_ptr->mStateQty =  sizeof(BkBtnTranTab)/sizeof(FtBtnTranTab[0]);
    InitUserButten(&g_btnRight);
    g_btnRight.mBtnStateMachine_ptr->mStateQty =  sizeof(RtBtnTranTab)/sizeof(FtBtnTranTab[0]);
    InitUserButten(&g_btnLeft);
    g_btnLeft.mBtnStateMachine_ptr->mStateQty =  sizeof(LfBtnTranTab)/sizeof(FtBtnTranTab[0]);
    InitUserButten(&g_btnAux1);
    g_btnAux1.mBtnStateMachine_ptr->mStateQty =  sizeof(Ax1BtnTranTab)/sizeof(FtBtnTranTab[0]);
    InitUserButten(&g_btnAux2);
    g_btnAux2.mBtnStateMachine_ptr->mStateQty =  sizeof(Ax2BtnTranTab)/sizeof(FtBtnTranTab[0]);
    InitUserButten(&g_btnAux3);
    g_btnAux3.mBtnStateMachine_ptr->mStateQty =  sizeof(Ax3BtnTranTab)/sizeof(FtBtnTranTab[0]);
    InitUserButten(&g_btnAux4);
    g_btnAux4.mBtnStateMachine_ptr->mStateQty =  sizeof(Ax4BtnTranTab)/sizeof(FtBtnTranTab[0]);

    return SUCCESS;
}
/*Button Scan*/
void userButtonScan(void)
{
    ListNode_t *tmp_ptr = &buttonListHead;
    while(tmp_ptr != NULL)
    {   /*scan all Button in Linklist*/
        ((struct buttonClass *)(tmp_ptr->Node_ptr))->getBtnStaus((struct buttonClass *)(tmp_ptr->Node_ptr));
        tmp_ptr = tmp_ptr->Next_ptr;
    }
}



static uint8_t InitUserButten(struct buttonClass *p)
{
    s_Statemachine_t *tmpButtenSM_ptr;
    tmpButtenSM_ptr = (s_Statemachine_t *)malloc(sizeof(s_Statemachine_t));
    if(tmpButtenSM_ptr==NULL)
    {
//        MALLOC_CHECKED_FAILD();
        LED_STAUS_SYS_INIT_FAULT();
        while(1)
            ;
    }
    /*Init ButtenSM in Default Val*/
    tmpButtenSM_ptr->mState = p->mSmDefaultState;
    tmpButtenSM_ptr->k_trans_ptr = p->mBtnTransTab_ptr;;

    p->mBtnStateMachine_ptr = tmpButtenSM_ptr;

    /*add In Linklist*/
    buttonList.Addlist(&buttonListHead,p);
    /*init_finished*/
    return SUCCESS;
}


static uint8_t FtBtnGetStaus(struct buttonClass *p)
{
    p->mButtonStaus = p->mBtnInputPin_ptr->mPinStatus;

    switch(p->mButtonStaus)
    {
    case 0:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_FtBtnDown);
        break;

    case 1:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_FtBtnUp);
        break;

    default:
        break;
    }
    return SUCCESS;
}

static uint8_t BkBtnGetStaus(struct buttonClass *p)
{
    p->mButtonStaus = p->mBtnInputPin_ptr->mPinStatus;

    switch(p->mButtonStaus)
    {
    case 0:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_BkBtnDown);
        break;

    case 1:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_BkBtnUp);
        break;

    default:
        break;
    }
    return SUCCESS;
}

static uint8_t RtBtnGetStaus(struct buttonClass *p)
{
    p->mButtonStaus = p->mBtnInputPin_ptr->mPinStatus;

    switch(p->mButtonStaus)
    {
    case 0:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_RtBtnDown);
        break;

    case 1:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_RtBtnUp);
        break;

    default:
        break;
    }
    return SUCCESS;
}
static uint8_t LfBtnGetStaus(struct buttonClass *p)
{
    p->mButtonStaus = p->mBtnInputPin_ptr->mPinStatus;

    switch(p->mButtonStaus)
    {
    case 0:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_LfBtnDown);
        break;

    case 1:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_LfBtnUp);
        break;

    default:
        break;
    }
    return SUCCESS;
}
static uint8_t Ax1BtnGetStaus(struct buttonClass *p)
{
    p->mButtonStaus = p->mBtnInputPin_ptr->mPinStatus;

    switch(p->mButtonStaus)
    {
    case 0:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_Ax1BtnDown);
        break;

    case 1:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_Ax1BtnUp);
        break;

    default:
        break;
    }
    return SUCCESS;
}
static uint8_t Ax2BtnGetStaus(struct buttonClass *p)
{
    p->mButtonStaus = p->mBtnInputPin_ptr->mPinStatus;

    switch(p->mButtonStaus)
    {
    case 0:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_Ax2BtnDown);
        break;

    case 1:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_Ax2BtnUp);
        break;

    default:
        break;
    }
    return SUCCESS;
}
static uint8_t Ax3BtnGetStaus(struct buttonClass *p)
{
    p->mButtonStaus = p->mBtnInputPin_ptr->mPinStatus;

    switch(p->mButtonStaus)
    {
    case 0:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_Ax3BtnDown);
        break;

    case 1:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_Ax3BtnUp);
        break;

    default:
        break;
    }
    return SUCCESS;
}

static uint8_t Ax4BtnGetStaus(struct buttonClass *p)
{
    p->mButtonStaus = p->mBtnInputPin_ptr->mPinStatus;

    switch(p->mButtonStaus)
    {
    case 0:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_Ax4BtnDown);
        break;

    case 1:
        RunStatemchine(p->mBtnStateMachine_ptr, EVENT_Ax4BtnUp);
        break;

    default:
        break;
    }
    return SUCCESS;
}

/*button Action Method Function*/
static void FtButtonAction(SmEvent_t* event_p)
{
    buttonTag_t buttonTag = BTN_FR;
    switch(*event_p)
    {
    case EVENT_FtBtnUp:
        ;
        break;
    case EVENT_FtBtnDown:
        remoteSysButtonAction(&buttonTag);
        break;
    default:
        break;
    }
}
static void BkButtonAction(SmEvent_t* event_p)
{
    buttonTag_t buttonTag = BTN_BK;
    switch(*event_p)
    {
    case EVENT_BkBtnUp:
        ;
        break;
    case EVENT_BkBtnDown:
        remoteSysButtonAction(&buttonTag);
        break;
    default:
        break;
    }
}
static void RtButtonAction(SmEvent_t* event_p)
{
    buttonTag_t buttonTag = BTN_RT;
    switch(*event_p)
    {
    case EVENT_RtBtnUp:
        ;
        break;
    case EVENT_RtBtnDown:
        remoteSysButtonAction(&buttonTag);
        break;
    default:
        break;
    }
}
static void LfButtonAction(SmEvent_t* event_p)
{
    buttonTag_t buttonTag = BTN_LF;
    switch(*event_p)
    {
    case EVENT_LfBtnUp:
        ;
        break;
    case EVENT_LfBtnDown:
        remoteSysButtonAction(&buttonTag);
        break;
    default:
        break;
    }
}
static void Ax1ButtonAction(SmEvent_t* event_p)
{
    buttonTag_t buttonTag = BTN_AX1;
    switch(*event_p)
    {
    case EVENT_Ax1BtnUp:
        ;
        break;
    case EVENT_Ax1BtnDown:
        remoteSysButtonAction(&buttonTag);
        break;
    default:
        break;
    }
}
static void Ax2ButtonAction(SmEvent_t* event_p)
{
    buttonTag_t buttonTag = BTN_AX2;
    switch(*event_p)
    {
    case EVENT_Ax2BtnUp:
        ;
        break;
    case EVENT_Ax2BtnDown:
        remoteSysButtonAction(&buttonTag);
        break;
    default:
        break;
    }
}
static void Ax3ButtonAction(SmEvent_t* event_p)
{
    buttonTag_t buttonTag = BTN_AX3;
    switch(*event_p)
    {
    case EVENT_Ax3BtnUp:
        ;
        break;
    case EVENT_Ax3BtnDown:
        remoteSysButtonAction(&buttonTag);
        break;
    default:
        break;
    }
}
static void Ax4ButtonAction(SmEvent_t* event_p)
{
    buttonTag_t buttonTag = BTN_AX4;
    switch(*event_p)
    {
    case EVENT_Ax4BtnUp:
        ;
        break;
    case EVENT_Ax4BtnDown:
        remoteSysButtonAction(&buttonTag);
        break;
    default:
        break;
    }
}









/*Format empty Function*/
//void SM_buttonAction(SmEvent_t* tmpEvent)
//{
//    ; /*empty Function*/
//}
